// string.hpp
//
// Copyright (C) 2008  Maksim Sipos <msipos@mailc.net>
//
// This file is a part of the Ripe language project.
//
// Ripe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include "util/standard.hpp"
#include <cstring>
#include <cstdio>
#include <stdarg.h>
#include "adts/string.hpp"
#include "util/mem.hpp"

namespace Ripe{

String::String()
{
  c_str = NULL;
}

String::String(char* s)
{
  c_str = mem_strdup(s);
}

String::String(const String& other)
{
  c_str = mem_strdup(other.c_str);
}

String& String::operator= (const String& other)
{
  if (this != &other) {
    if (c_str != NULL)
      free((void*) c_str);
    
    c_str = mem_strdup(other.c_str);  
  }
  return *this;
}

String& String::operator= (const char* s)
{
  if (c_str != NULL)
    free((void*) c_str);
  
  c_str = mem_strdup(s);
  return *this;
}

String::~String()
{
  if (c_str != NULL)
    free(c_str);
}

void String::format(const char* fmt, ...)
{
  #define STRING_FORMAT_BUFFER 2048
  va_list args;
  char buffer[STRING_FORMAT_BUFFER];

  va_start(args, fmt);
  std::vsnprintf(buffer, STRING_FORMAT_BUFFER, fmt, args);
  buffer[STRING_FORMAT_BUFFER - 1] = 0;

  if (c_str != NULL)
    free(c_str);
  c_str = mem_strdup(buffer);

  va_end(args);
}

StringBuffer::StringBuffer(uint32_t n)
{
  size = n;
  if (n == 0){
    buf = NULL;
    return;
  }
  buf = (char*) gc_malloc(size);
}

void StringBuffer::ensure(uint32_t new_size)
{
  if (size == 0 and new_size != 0){
    size = new_size;
    buf = (char*) gc_malloc(size);
    return;
  }

  if (new_size > size){
    size = new_size;
    buf = (char*) gc_realloc(buf, new_size);
  }
}

}
